package com.domainlanguage.time;

import org.hibernate.HibernateException;
import org.hibernate.type.ImmutableType;

import java.sql.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;

/**
 * Hibernate user type for {@link com.domainlanguage.time.TimePoint}.
 *
 * Backed by {@link java.sql.Types.TIMESTAMP}.
 *
 */
public class TimePointType extends ImmutableType {

    @Override
    public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
        final Timestamp timestamp = rs.getTimestamp(name);
        return timestamp == null ? null : TimePoint.from(timestamp);
    }

    @Override
    public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
        final TimePoint timePoint = (TimePoint) value;
        final long ms = timePoint.asJavaUtilDate().getTime();
        st.setTimestamp(index, new Timestamp(ms));
    }

    @Override
    public int sqlType() {
        return Types.TIMESTAMP;
    }

    // TODO use a defined date format pattern for to/from string

    @Override
    public String toString(Object value) throws HibernateException {
        final TimePoint timePoint = (TimePoint) value;
        final java.util.Date date = timePoint.asJavaUtilDate();

        return new SimpleDateFormat().format(date);
    }

    @Override
    public Object fromStringValue(String xml) throws HibernateException {
        try {
            return new SimpleDateFormat().parse(xml);
        } catch (ParseException e) {
            throw new HibernateException(e);
        }
    }

    @Override
    public Class getReturnedClass() {
        return TimePoint.class;
    }

    @Override
    public String getName() {
        return "timepoint";
    }

}
